#ifndef MODBUS_RTU_MAST_H
#define MODBUS_RTU_MAST_H

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

//参数类型
#define TLV_BOOL             1
#define TLV_TINY             43
#define TLV_UTINY            32
#define TLV_SHORT            33
#define TLV_USHORT           45
#define TLV_INT              2
#define TLV_UINT             35
#define TLV_LONG             36
#define TLV_ULONG            37
#define TLV_FLOAT            38
#define TLV_DOUBLE           39
#define TLV_STRING           4

#define MODBUS_READ_COILS                0x01
#define MODBUS_READ_DISCRETE_INPUTS      0x02
#define MODBUS_READ_HOLDING_REGISTERS    0x03
#define MODBUS_READ_INPUT_REGISTERS      0x04
#define MODBUS_WRITE_SINGLE_COIL         0x05
#define MODBUS_WRITE_SINGLE_REGISTER     0x06
#define MODBUS_READ_EXCEPTION_STATUS     0x07
#define MODBUS_WRITE_MULTIPLE_COILS      0x0F
#define MODBUS_WRITE_MULTIPLE_REGISTERS  0x10
#define MODBUS_REPORT_SLAVE_ID           0x11
#define MODBUS_MASK_WRITE_REGISTER       0x16
#define MODBUS_WRITE_AND_READ_REGISTERS  0x17

#define MD_RO   1                                                           //只读（常量）
#define MD_WO   2                                                           //只写（控制量）
#define MD_RW   3                                                           //可读可写（参数）

typedef struct 
{
    uint16_t    addr;                                                       //地址
    uint16_t    num;                                                        //个数
    uint16_t    RW;                                                         //属性按位标识     
    uint8_t     res_data_type;                                              //寄存器数据类型
    uint8_t     rel_data_type;                                              //实际数据类型
    float       ratio;                                                      //增益
    void        *offset;                                                    //数据地址偏移
    int         (*callback)(uint16_t offset, uint8_t *data, uint16_t len);  //回调函数sn:设备编号 data:数据 len:数据长度,返回：遥控情况
} modbus_table_t;

typedef struct 
{
    char*           dev;            //设备名称
    uint8_t         md_addr;        //modbus地址
    uint16_t        table_num;
    modbus_table_t  *table;
} modbus_page_t;

typedef struct
{
    uint8_t  func_code;
    uint16_t start_addr;
    uint16_t num;
}ModBus_03;


typedef struct
{
    uint8_t  addr_sn;
    uint16_t start_addr;
}ModBus_06;

void set_modbus_page(modbus_page_t *page, uint16_t num);
int read_AO(uint16_t addr_sn, uint16_t start_addr, uint16_t num, uint8_t *p_dst);
bool modbus_mast_decode(uint8_t *p_data, uint8_t len, uint16_t offset);
int white_more_AO(uint16_t addr_sn, uint16_t res_addr, uint8_t *p_dst);
int read_input_AO(uint16_t addr_sn, uint16_t start_addr, uint16_t num, uint8_t *p_dst);

#endif
